/*
 * Copyright (C) 2017 Intel Corporation.  All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */

// Copyright (c) WanSheng Intelligent Corp. All rights reserved.


#define LOG_TAG "AMS"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include "path.h"
#include "misc.h"
#include <sys/types.h>  
#include <sys/stat.h>
#include "logs.h"
#include "ams_constants.h"

// note: the path returned must end with '/'


static char bin_path[PATH_LEN] = {0};
static char generic_path[PATH_LEN] = {0};

extern char * getExecPath (char * path,size_t dest_len, char * argv0);


void path_init(char* exec)
{
    char buf[PATH_LEN];

    getExecPath(buf, sizeof(buf), exec);

    ams_locate_product_path(buf, bin_path);

    make_full_dir(get_log_path());
    make_full_dir(get_config_path());
    make_full_dir(get_tmp_path());
    make_full_dir(get_cache_path());

    int stat = chmod(get_log_path(), S_IRWXU|S_IRWXG|S_IRWXO);
    if(stat)
    {
        WARNING2("Failed to change log dir to other writeable. %d", stat);
    }

    stat = chmod(get_tmp_path(), S_IRWXU|S_IRWXG|S_IRWXO);
    if(stat)
    {
         WARNING2("Failed to change tmp dir to other writeable. %d", stat);
    }
}



// guartenteed path will end with '/'
char * get_ams_root(char * path, int len)
{
    char * path_env = getenv( "AMS_CLIENT_BASE_DIR");
    if(read_global_setting(CONF_KEY_AMS_ROOT, path, len))
    {
        printf("get_ams_root: loaded from the sys config: %s\n", path);
    }
    
    else if( ( NULL != path_env && strlen(path_env) > 2 ) )
    {
        strncpy(path, path_env, len);
        path[len - 1] = 0;
        printf("get_ams_root: loaded from the env [AMS_CLIENT_BASE_DIR]: %s\n", path);
    }
    else 
    {
        strncpy(path, "/ams/", len);
    }

    if (access(path, R_OK) != 0)
    {
        make_full_dir(path);
    }
    int l = strlen(path);
    if(path[ l-1] != '/' && l<len-1)
    {
        path[ l] = '/';
        path[ l+1] = 0;
    }

    return path;
}


// the root dir where ams and other products are installed
// note: the root dir doesn't neccessary be together with the ams binary.
//       it can configured in the /etc/ams/wasome.cfg or the environment
char * get_ams_root_dir()
{
	static char * ams_root = NULL;
	if(ams_root) return ams_root;

	char path[PATH_LEN];
	if(get_ams_root(path, sizeof(path)))
	{
		ams_root = strdup(path);
        return ams_root;
	}
	else
	{
		return "/ams/";
	}
}

// guartenteed path will end with '/'
char * get_plc_framework_root(char * path, int len)
{

    char * path_env = getenv( "WA_PLC_BASE_DIR");
    if(read_global_setting(CONF_KEY_WAPLC_ROOT, path, len))
    {
        printf("get_plc_framework_root: loaded from the sys config: %s\n", path);
    }
    else if( ( NULL != path_env && strlen(path_env) > 2 ) )
    {
        strncpy(path, path_env, len);
        path[len - 1] = 0;
        printf("get_plc_framework_root: loaded from the env [WA_PLC_BASE_DIR]: %s\n", path);
    }
    else
    {
        strncpy(path, "/wa-plc/", len);
        path[len - 1] = 0;
    }
    if (access(path, R_OK) != 0)
    {
        make_full_dir(path);
    }
    int l = strlen(path);
    if(path[ l-1] != '/' && l<len-1)
    {
        path[ l] = '/';
        path[ l+1] =0;
    }
    return path;
}


char * get_ams_config_path(char * path, int len)
{
    if(get_ams_root(path, len) == NULL)
        return NULL;

    if((strlen(path) + 40) > len)
        return NULL;

    strcat(path, "/ams_client/config/ams.cfg");

    return path;
}



char* get_root_path()
{
    return ams_my_product_root(NULL, PATH_LEN);

}

// try to locate the log path from env variable AMS_LOG_PATH first,
// if it doesn't work, use the ams path folder as log path
char* get_log_path()
{
    memset(generic_path, 0, sizeof(generic_path));
    if(read_global_setting(CONF_KEY_LOGGING_DIR, generic_path, sizeof(generic_path) ))
    {
        int l = strlen(generic_path);
        if(generic_path[ l-1] != '/' && l<sizeof(generic_path)-1)
        {
            generic_path[ l] = '/';
        }
        printf("get_log_path: loaded from the sys config: %s\n", generic_path);
        return generic_path;
    }

    char * path_env = getenv( "AMS_LOG_PATH");
    if( ( NULL != path_env && strlen(path_env) > 1 ) )
    {
        strncpy(generic_path,path_env, sizeof(generic_path) -2);
        printf("get_log_path:AMS_LOG_PATH variable is [%s]\n", generic_path);
        make_full_dir(path_env);
        DIR* dir = opendir(path_env);
        if (dir) {
          closedir(dir);
          if(generic_path[strlen(generic_path)-1] != '/')
              strcat(generic_path, "/");
          return generic_path;
        }
    }

    char *path_name = ams_my_product_root(generic_path, sizeof(generic_path));
    strcat(path_name,"logs/");
    return path_name;
}

char* get_config_path()
{
    ams_my_product_root(generic_path, sizeof(generic_path));
    strcat(generic_path, "config/");
    return generic_path;
}

// load from the product config dir first. If not present, then try it in the bin path
char * get_log_cfg_path(char * buf, int size, const char * logcfg_name)
{
    snprintf(buf, size, "%s%s",get_config_path(), logcfg_name);
    if(access(buf, F_OK) == 0)
        return buf;

    snprintf(buf, size, "%s%s",get_bin_path(), logcfg_name);
    return buf;
}


char *get_device_config_pathname(char *config_pathname, char * buffer, int buf_len)
{
    return get_product_config_pathname(config_pathname, TT_DEVICE, NULL, buffer);
}

//
// the file path for a configuration file:
//    [root config dir]/[:target_type]/[:target_id]/[:config_path_name]
// note: when target type is TT_DEVICE, there is no section of "target id".
//
//
char *get_product_config_pathname(char *config_pathname, char* target_type, char * target_id, char * buffer)
{
    char * out_path = buffer;
    if(out_path == NULL) out_path = &generic_path[0];
    strcpy(out_path, get_config_path());
    strcat(out_path, target_type);
    strcat(out_path, "/");
    if(strcmp(TT_DEVICE, target_type) != 0 && target_id && *target_id != 0)
    {
        strcat(out_path, target_id);
        if(*config_pathname != '/'){
            strcat(out_path, "/");
        }
    }

    strcat(out_path, config_pathname);
    return out_path;
}

char* get_bin_path()
{
    return bin_path;
}

char* get_tools_path()
{
    ams_my_product_root(generic_path, sizeof(generic_path));
    strcat(generic_path,  "tools/");
    return generic_path;
}

char* get_tmp_path()
{
    ams_get_temp_root(generic_path, sizeof(generic_path));
    return generic_path;
}


char* get_cache_path()
{
    ams_my_product_root(generic_path, sizeof(generic_path));
    strcat(generic_path,  "data_cache/");
    return generic_path;
}


char * get_local_config_path(char * cfgname, int len, char * config_name)
{
    snprintf(cfgname, len, "%s%s",get_bin_path(), config_name);
    return cfgname;
}
